﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Graph2
{
    public partial class MainForm : Form
    {
		private Axes m_Axes = new Axes();
		private bool m_Panning = false;
		private Point m_PanStart;
		private bool m_StartZoomingBox = false;
		private bool m_ZoomingBox = false;
		private Point m_ZoomBoxStart;
		private Point m_ZoomBoxEnd;

		private List<Function> m_Functions;

        public MainForm()
        {
            InitializeComponent();

			m_Functions = new List<Function>();
        }

        private void GraphDisplay_Paint(object sender, PaintEventArgs e)
        {
			m_Axes.Draw(e.Graphics);
			if (m_ZoomingBox)
			{
				Pen rectPen = new Pen(Color.Black, 1);
				rectPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
				int startX = Math.Min(m_ZoomBoxStart.X, m_ZoomBoxEnd.X);
				int startY = Math.Min(m_ZoomBoxStart.Y, m_ZoomBoxEnd.Y);
				int width = Math.Abs(m_ZoomBoxEnd.X - m_ZoomBoxStart.X);
				int height = Math.Abs(m_ZoomBoxEnd.Y - m_ZoomBoxStart.Y);

				e.Graphics.DrawRectangle(rectPen, startX, startY, width, height); 
			}
        }

		private void MainForm_Load(object sender, EventArgs e)
		{
			m_Axes.SetScreenSize(GraphDisplay.Width, GraphDisplay.Height);
			GraphDisplay.Refresh();
		}

		private void GraphDisplay_Resize(object sender, EventArgs e)
		{
			m_Axes.SetScreenSize(GraphDisplay.Width, GraphDisplay.Height);
		}

		private void MainForm_Resize(object sender, EventArgs e)
		{
			m_Axes.SetScreenSize(GraphDisplay.ClientSize.Width, GraphDisplay.ClientSize.Height);
			GraphDisplay.Refresh();
		}

		private void GraphDisplay_MouseDown(object sender, MouseEventArgs e)
		{
			if (m_StartZoomingBox)
			{
				m_ZoomingBox = true;
				m_StartZoomingBox = false;
				m_ZoomBoxStart = e.Location;
				GraphDisplay.Capture = true;
			}
			else
			{
				GraphDisplay.Cursor = new Cursor(new System.IO.MemoryStream(Graph2Res.HandMoveCursor));
				GraphDisplay.Capture = true;
				m_Panning = true;
				m_PanStart = e.Location;
				m_Axes.StartTranslate();
			}
		}

		private void GraphDisplay_MouseUp(object sender, MouseEventArgs e)
		{
			GraphDisplay.Cursor = Cursors.Default;
			GraphDisplay.Capture = false;
			m_Panning = false;
			if (m_ZoomingBox)
			{
				m_Axes.Zoom(m_ZoomBoxStart, m_ZoomBoxEnd);
			}
			m_ZoomingBox = false;
			GraphDisplay.Refresh();
		}

		private void GraphDisplay_MouseMove(object sender, MouseEventArgs e)
		{
			if (m_Panning)
			{
				m_Axes.Translate(e.Location.X - m_PanStart.X, -(e.Location.Y - m_PanStart.Y));
				GraphDisplay.Refresh();
			}
			else if (m_ZoomingBox)
			{
				m_ZoomBoxEnd = e.Location;
				GraphDisplay.Refresh();
			}
			else
			{
				PointF pf = m_Axes.ToAxes(e.X, e.Y);
				CursorAxesPosLbl.Text = "(" + pf.X.ToString("0.##") + " , " + pf.Y.ToString("0.##") + ")";
			}
		}

		private void ZoomBoxBtn_Click(object sender, EventArgs e)
		{
			m_StartZoomingBox = true;
			GraphDisplay.Cursor = Cursors.Cross;
		}

		private void ResetZoomBtn_Click(object sender, EventArgs e)
		{
			m_Axes.ResetZoom();
			GraphDisplay.Refresh();
		}

		private void RefreshFunctionList()
		{
			FunctionList.Items.Clear();
			for (int i = 0; i < m_Functions.Count; ++i)
			{
				ListViewItem lvi = FunctionList.Items.Add(i.ToString(), m_Functions[i].Name, "function_icon");
				lvi.Checked = m_Functions[i].Enabled;
			}
		}

		private void ShowInsertFunctionDialog()
		{
			FunctionForm frm = new FunctionForm();
			if (frm.ShowDialog(this) == DialogResult.OK)
			{
				m_Functions.Add(frm.Function);
				RefreshFunctionList();
			}
		}

		private void inserToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ShowInsertFunctionDialog();
		}

		private void InsertFunctionBtn_Click(object sender, EventArgs e)
		{
			ShowInsertFunctionDialog();
		}

		private void FunctionList_Resize(object sender, EventArgs e)
		{
			FunctionList.Columns[0].Width = FunctionList.Width;
		}
    }
}
